#ifndef SHARED_STRUCTURE
#define SHARED_STRUCTURE
#include <list>
#include <deque>
#include <vector>

#define USE_OPEN_CV
//#define USE_SIMD
//#define LENGTH_NORMALIZE
//#define AREA_NORMALIZE
//#define COMPLEXITY_NORMALIZE

#define USE_COLOR
//#define USE_L_COLOR

//#define USE_FLAT


#define ROUND(x) floor(x + 0.5f);
const float PI = 3.1415926f;
const double MD_PI =3.14159265358979323846;
const float NEGMAX = -1e9;
const int PR_QUEUE_SIZE = 20;



struct gabor{
	int x; // position along vertical axis
	int y; // position along horizontal axis
	int orient;// orientation. strart from horizontal, grows anti-clockwise
};

struct line{
	int x; // center position along vertical axis
	int y; // center position along horizontal axis
	int orient;//the same for structure gabor
	int length; // length fo the line.
};


struct lineVertex{
	float x_start,x_end,y_start,y_end;
};


struct deformation{
	std::deque<lineVertex> line_list;
};

struct activeShape{
	std::deque<lineVertex> line_list;
	std::deque<deformation> deformation_list;
	enum shapeType {CIRCLE, LINE, PARA_LINE, TRAPEZOIDS};
	shapeType type;
};

struct plane{
	float nt[4];
	float origin[3];
	float bu[3];
	float bv[3];
	float width;
	float height;
	float stp;
};

struct line3D{
	float x1,y1,z1;
	float x2,y2,z2;
};



struct pt_pair_s{
	float pts[5];
	float& operator[](const int &i){return pts[i];};
	const float& operator[](const int &i) const {return pts[i];};

/*
	pt_pair_s(){};

	pt_pair_s(const pt_pair_s &p){
	for( int i= 0; i<5; ++i) pts[i]=p.pts[i];
	}

 pt_pair_s& operator=(const pt_pair_s &p){
		for( int i =0; i<5; ++i) pts[i]=p.pts[i];
		return *this;
	}
*/
	/*
	const pt_pair_s& operator=(const pt_pair_s &p){
		for( int i =0; i<5; ++i) pts[i]=p.pts[i];
	}
	*/
};



struct tanParticle_s{
	float P[3][4];
	float cam_dir[3];
	float fit_error;
	float score;
	int arg_max_deformation;
	int id;
	float color_feature[30];
	float flat_feature[10];
	std::deque<pt_pair_s> pt_pairs;
	std::deque<float> response;
	std::deque<int> line_length;
	bool operator<(tanParticle_s &that){
		return this->score<that.score;
	}

	/*
	tanParticle_s(){};

	tanParticle_s(const tanParticle_s &tan){
		memcpy(this->cam_dir,tan.cam_dir,sizeof(float)*3);
		memcpy(this->P[0],tan.P[0],sizeof(float)*4);
		memcpy(this->P[1],tan.P[1],sizeof(float)*4);
		memcpy(this->P[2],tan.P[2],sizeof(float)*4);
		fit_error = tan.fit_error;
		score = tan.score;
		arg_max_deformation = tan.arg_max_deformation;
		id = tan.id;
		for( int i = 0; i<tan.pt_pairs.size(); ++i) pt_pairs.push_back(tan.pt_pairs[i]);
	}
*/
};

struct volParticle_s{
	std::vector<tanParticle_s> tan_particle_list;
	std::deque<int> deform_list;
	float score;
	float P[3][4];
	float cam_dir[3];
	float fit_error;
	int id;
		bool operator<(volParticle_s &that){
		return this->score<that.score;
	}
};

struct rootParticle_s{
	std::vector<volParticle_s> vol_particle_list;
	std::vector<int> or_index_list;
	int bb_size; // bounding box size
	float score;
	float P[3][4];
	float cam_dir[3];
	float fit_error;
	int id;
	bool operator<(rootParticle_s &that){
		return this->score>that.score;
	}
	rootParticle_s(){ bb_size=0;};
};

const int palette[][3]={{   0   ,0   ,255},
{   0   ,255   ,0},
{   255   ,0   ,0},
{   216   ,191   ,216},
{   128     ,0   ,128},
{    75     ,0   ,130},
{   220    ,20    ,60},
{   128   ,128     ,0},
{   250   ,128   ,114},
{   176   ,196   ,222},
{   255   ,160   ,122},
{   176   ,224   ,230},
{   255   ,182   ,193},
{   107   ,142    ,35},
{   138    ,43   ,226},
{   144   ,238   ,144},
{    65   ,105   ,225},
{     0   ,139   ,139},
{    30   ,144   ,255},
{     0     ,0   ,255},
{   135   ,206   ,250},
{   127   ,255   ,212},
{   173   ,216   ,230},
{     0   ,128     ,0},
{   139     ,0   ,139},
{   255     ,0     ,0},
{   143   ,188   ,143},
{     0     ,0   ,128},
{     0   ,255     ,0},
{   186    ,85   ,211},
{   255   ,127    ,80},
{   124   ,252     ,0},
{     0   ,255   ,127},
{     0     ,0   ,139},
{   199    ,21   ,133},
{     0   ,250   ,154},
{    85   ,107    ,47},
{    64   ,224   ,208},
{   178    ,34    ,34},
{    70   ,130   ,180},
{    32   ,178   ,170},
{     0     ,0   ,205},
{   255   ,160   ,122},
{    60   ,179   ,113},
{   154   ,205    ,50},
{   147   ,112   ,219},
{   255   ,165     ,0},
{   218   ,112   ,214},
{     0   ,100     ,0},
{    72    ,61   ,139},
{    72   ,209   ,204},
{   148     ,0   ,211},
{    46   ,139    ,87},
{   255     ,0   ,255},
{     0   ,128   ,128},
{    34   ,139    ,34},
{   255     ,0   ,255},
{    50   ,205    ,50},
{   255    ,69     ,0},
{   152   ,251   ,152},
{   219   ,112   ,147},
{     0   ,191   ,255},
{   205    ,92    ,92},
{   106    ,90   ,205},
{    25    ,25   ,112},
{   135   ,206   ,235},
{   221   ,160   ,221},
{     0   ,206   ,209},
{   240   ,128   ,128},
{   233   ,150   ,122},
{   255    ,99    ,71},
{   100   ,149   ,237},
{   238   ,130   ,238},
{   173   ,255    ,47},
{   255    ,20   ,147},
{   139     ,0     ,0},
{    95   ,158   ,160},
{   255   ,140     ,0},
{   102   ,205   ,170},
{   255   ,192   ,203},
{   255   ,105   ,180}};


struct view_s{
	float pan,tilt,roll; /*in degree*/
	float distance; /*in meter*/
	float tx,ty,tz;

	float min_x,max_x,min_y,max_y;
	float P[3][4];
	float cam_dir[3];
	float zx,zy;/*for loaded P from labeld image.*/
};

#endif
